/*
 * Copyright (c) 2024 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

#include <devmon/driver_abi.h>
#include <dlfcn.h>
#include <gtest/gtest.h>
#include <test_utilities/test_base.h>
#include <mc/common.h>
#include <ncsi/ncsi_socket.h>
#include <ncsi/ncsi_protocol.h>

#include "hi182x/hi182x_card.h"
#include "hi182x/hi182x_om.h"
#include "hi182x/hi182x_port.h"

using namespace dev;

namespace drivers {
namespace pcie_nic_card {
namespace hisi {

namespace test {

class hi182x_test_service : public mc::engine::service {
public:
    hi182x_test_service(const std::string& name) : mc::engine::service(name) {
    }
};

class Hi182xAbiTest : public mc::test::TestWithEngine {
public:
    static void SetUpTestSuite() {
        TestWithEngine::SetUpTestSuite();
        m_test_service.init();
        m_test_service.start();
        load_driver();
    }

    static void TearDownTestSuite() {
        m_test_service.stop();
        if (m_driver_handle != nullptr) {
            dlclose(m_driver_handle);
            m_driver_handle = nullptr;
        }
        TestWithEngine::TearDownTestSuite();
    }

    void SetUp() override {
    }

    void TearDown() override {
    }

    static void load_driver() {
        m_driver_handle = dlopen("./opt/bmc/drivers/libhisi_182x.so", RTLD_LAZY);
        if (m_driver_handle == nullptr) {
            MC_THROW(mc::system_exception, "Failed to load driver: ${error}", ("error", dlerror()));
        }
        register_device_driver_func func = reinterpret_cast<register_device_driver_func>(
            dlsym(m_driver_handle, "register_device_driver"));
        MC_ASSERT_THROW(func, mc::bad_function_call_exception,
                        "Failed to get export_device_driver function: ${error}",
                        ("error", dlerror()));

        device_driver_t* devices       = nullptr;
        uint8_t          devices_count = 0;
        status_t         ret           = func(&devices, &devices_count);
        MC_ASSERT_THROW(ret == STATUS_OK, mc::bad_function_call_exception,
                        "Failed to get device driver manager: ${error}", ("error", ret));

        m_devices.clear();
        m_devices.reserve(devices_count);
        for (uint8_t i = 0; i < devices_count; i++) {
            auto device_driver = std::make_shared<device_driver_t>(devices[i]);
            m_devices.emplace(device_driver->device_name, device_driver);
        }
    }

    mc::dict create_test_connector(uint8_t system_id, uint8_t position, uint8_t slot) {
        return mc::dict{{"SystemId", system_id}, {"Position", position}, {"Slot", slot}};
    }

    static hi182x_test_service                                               m_test_service;
    static std::unordered_map<std::string, std::shared_ptr<device_driver_t>> m_devices;
    static void*                                                             m_driver_handle;
};

hi182x_test_service Hi182xAbiTest::m_test_service{"bmc.kepler.test_hi182x"};
std::unordered_map<std::string, std::shared_ptr<device_driver_t>> Hi182xAbiTest::m_devices;
void* Hi182xAbiTest::m_driver_handle = nullptr;

// ========================= 驱动注册功能测试 =========================

TEST_F(Hi182xAbiTest, register_device_driver_success) {
    // 验证驱动注册成功，并且包含预期的设备类型
    EXPECT_EQ(m_devices.size(), 3);
    EXPECT_TRUE(m_devices.find("PCIeNicCard") != m_devices.end());
    EXPECT_TRUE(m_devices.find("NicPort") != m_devices.end());
    EXPECT_TRUE(m_devices.find("OpticalTransceiver") != m_devices.end());
}

TEST_F(Hi182xAbiTest, device_driver_structure_validation) {
    // 验证每个设备驱动的结构完整性
    for (const auto& [device_name, device_driver] : m_devices) {
        EXPECT_FALSE(std::string(device_driver->device_name).empty());
        EXPECT_TRUE(device_driver->ctor != nullptr);
        EXPECT_TRUE(device_driver->init != nullptr);
        EXPECT_TRUE(device_driver->start != nullptr);
        EXPECT_TRUE(device_driver->stop != nullptr);
    }
}

// ========================= PCIeNicCard设备测试 =========================

TEST_F(Hi182xAbiTest, create_hi182x_card_success) {
    auto device_driver = m_devices["PCIeNicCard"];
    ASSERT_TRUE(device_driver != nullptr);

    auto device = device_driver->ctor(&m_test_service, "hi182x_card");
    ASSERT_TRUE(device != nullptr);
}

TEST_F(Hi182xAbiTest, create_hi182x_card_null_service) {
    auto device_driver = m_devices["PCIeNicCard"];
    ASSERT_TRUE(device_driver != nullptr);

    // 传入空服务指针应该返回nullptr
    auto device = device_driver->ctor(nullptr, "hi182x_card");
    EXPECT_EQ(device, nullptr);
}

TEST_F(Hi182xAbiTest, init_hi182x_card_null_params) {
    auto device_driver = m_devices["PCIeNicCard"];
    ASSERT_TRUE(device_driver != nullptr);

    auto device = device_driver->ctor(&m_test_service, "hi182x_card_null_test");
    ASSERT_TRUE(device != nullptr);

    // 测试空参数初始化
    status_t ret = device_driver->init(device, nullptr, nullptr);
    EXPECT_EQ(ret, STATUS_ERROR);
}

TEST_F(Hi182xAbiTest, test_hi182x_card_init) {
    auto device_driver = m_devices["PCIeNicCard"];
    ASSERT_TRUE(device_driver != nullptr);

    auto device = static_cast<hi182x_card*>(device_driver->ctor(&m_test_service, "hi182x_card_lifecycle"));
    ASSERT_TRUE(device != nullptr);

    auto config = mc::mutable_dict({
        {"SystemId", 1}
    });
    EXPECT_TRUE(device->init(config, mc::dict()));
    EXPECT_EQ(device->m_system_id, 1);
}

TEST_F(Hi182xAbiTest, test_hi182x_card_start_with_network_ports) {
    auto device_driver = m_devices["PCIeNicCard"];
    ASSERT_TRUE(device_driver != nullptr);

    auto device = static_cast<hi182x_card*>(device_driver->ctor(&m_test_service, "hi182x_card_lifecycle"));
    ASSERT_TRUE(device != nullptr);

    auto config = mc::mutable_dict({
        {"SystemId", 1}
    });
    EXPECT_TRUE(device->init(config, mc::dict()));

    auto port_driver = m_devices["NicPort"];
    ASSERT_TRUE(port_driver != nullptr);

    auto port_device = static_cast<hi182x_port*>(port_driver->ctor(&m_test_service, "hi182x_port"));
    ASSERT_TRUE(port_device != nullptr);
    auto port_config = mc::mutable_dict({
        {"bmc.dev.NetworkPort", mc::dict{{"PortId", 1}, {"MACAddress", "00:11:22:33:44:55"}}}
    });
    EXPECT_TRUE(port_device->init(port_config, mc::dict()));
    port_device->set_parent(device);

    auto om_driver = m_devices["OpticalTransceiver"];
    ASSERT_TRUE(om_driver != nullptr);

    auto om_device = static_cast<hi182x_optical_module*>(om_driver->ctor(&m_test_service, "hi182x_om"));
    ASSERT_TRUE(om_device != nullptr);
    om_device->set_parent(port_device);

    EXPECT_TRUE(device->start());
    EXPECT_TRUE(device->stop());
}

// ========================= NicPort设备测试 =========================

TEST_F(Hi182xAbiTest, create_hi182x_port_success) {
    auto device_driver = m_devices["NicPort"];
    ASSERT_TRUE(device_driver != nullptr);

    auto device = device_driver->ctor(&m_test_service, "hi182x_port");
    ASSERT_TRUE(device != nullptr);
}

TEST_F(Hi182xAbiTest, create_hi182x_port_null_service) {
    auto device_driver = m_devices["NicPort"];
    ASSERT_TRUE(device_driver != nullptr);

    // 传入空服务指针应该返回nullptr
    auto device = device_driver->ctor(nullptr, "hi182x_port");
    EXPECT_EQ(device, nullptr);
}

TEST_F(Hi182xAbiTest, init_hi182x_port_null_params) {
    auto device_driver = m_devices["NicPort"];
    ASSERT_TRUE(device_driver != nullptr);

    auto device = device_driver->ctor(&m_test_service, "hi182x_port_null_test");
    ASSERT_TRUE(device != nullptr);

    // 测试空参数初始化
    status_t ret = device_driver->init(device, nullptr, nullptr);
    EXPECT_EQ(ret, STATUS_ERROR);
}

TEST_F(Hi182xAbiTest, init_hi182x_port_with_params) {
    auto device_driver = m_devices["NicPort"];
    ASSERT_TRUE(device_driver != nullptr);

    auto device = static_cast<hi182x_port*>(
        device_driver->ctor(&m_test_service, "hi182x_port_lifecycle"));
    ASSERT_TRUE(device != nullptr);

    auto config = mc::mutable_dict({
        {"bmc.dev.NetworkPort", mc::dict{{"PortId", 1}, {"MACAddress", "00:11:22:33:44:55"}}}
    });
    EXPECT_TRUE(device->init(config, mc::dict()));
    EXPECT_EQ(device->m_network_port.PortId.get_value(), 1);
    EXPECT_EQ(device->m_network_port.MACAddress.get_value(), "00:11:22:33:44:55");
}

TEST_F(Hi182xAbiTest, test_hi182x_NetworkPort_start_with_om) {
    auto device_driver = m_devices["NicPort"];
    ASSERT_TRUE(device_driver != nullptr);

    auto device = static_cast<hi182x_port*>(
        device_driver->ctor(&m_test_service, "hi182x_port_lifecycle"));
    ASSERT_TRUE(device != nullptr);

    auto config = mc::mutable_dict({
        {"bmc.dev.NetworkPort", mc::dict{{"PortId", 1}, {"MACAddress", "00:11:22:33:44:55"}}}
    });
    EXPECT_TRUE(device->init(config, mc::dict()));
    
    auto om_device = static_cast<hi182x_optical_module*>(
        device_driver->ctor(&m_test_service, "OpticalTransceiver_om1"));
    ASSERT_TRUE(om_device != nullptr);
    om_device->set_parent(device);

    EXPECT_TRUE(device->start());
    EXPECT_TRUE(device->stop());
    EXPECT_EQ(om_device->m_optical_module.PortId.get_value(), 1);
}

TEST_F(Hi182xAbiTest, test_hi182x_NetworkPort_start_multiple_om) {
    auto device_driver = m_devices["NicPort"];
    ASSERT_TRUE(device_driver != nullptr);

    auto device = static_cast<hi182x_port*>(
        device_driver->ctor(&m_test_service, "hi182x_port_lifecycle"));
    ASSERT_TRUE(device != nullptr);

    auto config = mc::mutable_dict({
        {"bmc.dev.NetworkPort", mc::dict{{"PortId", 1}, {"MACAddress", "00:11:22:33:44:55"}}}
    });
    EXPECT_TRUE(device->init(config, mc::dict()));
    
    auto om_driver = m_devices["OpticalTransceiver"];
    ASSERT_TRUE(om_driver != nullptr);

    auto om_device1 = static_cast<hi182x_optical_module*>(
        om_driver->ctor(&m_test_service, "hi182x_om1"));
    ASSERT_TRUE(om_device1 != nullptr);
    om_device1->set_parent(device);

    auto om_device2 = static_cast<hi182x_optical_module*>(
        om_driver->ctor(&m_test_service, "hi182x_om2"));
    ASSERT_TRUE(om_device2 != nullptr);
    om_device2->set_parent(device);

    EXPECT_FALSE(device->start());
    EXPECT_TRUE(device->stop());
    EXPECT_NE(om_device1->m_optical_module.PortId.get_value(), 1);
    EXPECT_NE(om_device2->m_optical_module.PortId.get_value(), 1);
}

TEST_F(Hi182xAbiTest, test_hi182x_NetworkPort_verify_did_vid_svid_sdid) {
    auto device_driver = m_devices["NicPort"];
    ASSERT_TRUE(device_driver != nullptr);

    auto device = static_cast<hi182x_port*>(
        device_driver->ctor(&m_test_service, "hi182x_port_lifecycle"));
    ASSERT_TRUE(device != nullptr);

    auto config = mc::mutable_dict({
        {"bmc.dev.NetworkPort", mc::dict{{"PortId", 1}, {"MACAddress", "00:11:22:33:44:55"}}}
    });
    EXPECT_TRUE(device->init(config, mc::dict()));

    imu_pcie_device_req_t pcie_device_info;
    pcie_device_info.bus = 0;
    pcie_device_info.device = 0;
    pcie_device_info.function = 0;

    EXPECT_NO_THROW({
        device->verify_did_vid_svid_sdid(pcie_device_info);
    });
    
    // 数据格式：{0xe5, 0x19, 0x22, 0x18}
    // device_id = data[3] + (data[2] << 8) = 0x18 + (0x22 << 8) = 0x2218
    // vendor_id = data[1] + (data[0] << 8) = 0x19 + (0xe5 << 8) = 0xe519
    std::vector<uint8_t> vid_did_data = {0xe5, 0x19, 0x22, 0x18};
    uint16_t device_id = (vid_did_data[3] & 0xff) | (vid_did_data[2] & 0xff) << 8;
    uint16_t vendor_id = (vid_did_data[1] & 0xff) | (vid_did_data[0] & 0xff) << 8;
    
    EXPECT_EQ(vendor_id, 0xe519);  // 0x19 + (0xe5 << 8)
    EXPECT_EQ(device_id, 0x2218);  // 0x18 + (0x22 << 8)
    EXPECT_FALSE(vendor_id == 0xffff && device_id == 0xffff);
    
    std::vector<uint8_t> invalid_data = {0xFF, 0xFF, 0xFF, 0xFF};
    uint16_t invalid_device_id = (invalid_data[3] & 0xff) | (invalid_data[2] & 0xff) << 8;
    uint16_t invalid_vendor_id = (invalid_data[1] & 0xff) | (invalid_data[0] & 0xff) << 8;
    
    EXPECT_EQ(invalid_vendor_id, 0xFFFF);
    EXPECT_EQ(invalid_device_id, 0xFFFF);
    EXPECT_TRUE(invalid_vendor_id == 0xffff && invalid_device_id == 0xffff);
    
    std::vector<uint8_t> short_data = {0xe5, 0x19}; // 只有2字节
    EXPECT_LT(short_data.size(), 4);
    
    const uint8_t VID_DID_ADDRESS = 0x00;
    const uint8_t SVID_SDID_ADDRESS = 0x2C;
    EXPECT_EQ(VID_DID_ADDRESS, 0x00);
    EXPECT_EQ(SVID_SDID_ADDRESS, 0x2C);
}

TEST_F(Hi182xAbiTest, test_hi182x_NetworkPort_update_port_bdf) {
    auto device_driver = m_devices["NicPort"];
    ASSERT_TRUE(device_driver != nullptr);

    auto device = static_cast<hi182x_port*>(
        device_driver->ctor(&m_test_service, "hi182x_port_lifecycle"));
    ASSERT_TRUE(device != nullptr);

    auto config = mc::mutable_dict({
        {"bmc.dev.NetworkPort", mc::dict{{"PortId", 1}, {"MACAddress", "00:11:22:33:44:55"}}}
    });
    EXPECT_TRUE(device->init(config, mc::dict()));
    
    imu_pcie_device_req_t pcie_device_info;
    pcie_device_info.bus = 0;
    pcie_device_info.device = 0;
    pcie_device_info.function = 0;

    EXPECT_NO_THROW({
        device->update_port_bdf(pcie_device_info);
    });
    
    // 模拟BDF计算：bus = original_bus + PortId
    uint8_t original_bus = 0;
    uint8_t port_id = 1;
    uint8_t calculated_bus = original_bus + port_id;
    EXPECT_EQ(calculated_bus, 1);
    
    // 测试3: 验证BDF字符串格式化
    std::string expected_bdf = std::to_string(calculated_bus) + ":" + 
                              std::to_string(pcie_device_info.device) + "." + 
                              std::to_string(pcie_device_info.function);
    EXPECT_EQ(expected_bdf, "1:0.0");
    
    EXPECT_EQ(device->m_network_port.PortId, 1);
    
    EXPECT_EQ(device->m_network_port.MACAddress.get_value(), "00:11:22:33:44:55");
}

// ========================= OpticalTransceiver设备测试 =========================

TEST_F(Hi182xAbiTest, create_hi182x_optical_module_success) {
    auto device_driver = m_devices["OpticalTransceiver"];
    ASSERT_TRUE(device_driver != nullptr);

    auto device = device_driver->ctor(&m_test_service, "hi182x_optical_module");
    ASSERT_TRUE(device != nullptr);
}

TEST_F(Hi182xAbiTest, create_hi182x_optical_module_null_service) {
    auto device_driver = m_devices["OpticalTransceiver"];
    ASSERT_TRUE(device_driver != nullptr);

    // 传入空服务指针应该返回nullptr
    auto device = device_driver->ctor(nullptr, "hi182x_optical_module");
    EXPECT_EQ(device, nullptr);
}

TEST_F(Hi182xAbiTest, init_hi182x_optical_module_null_params) {
    auto device_driver = m_devices["OpticalTransceiver"];
    ASSERT_TRUE(device_driver != nullptr);

    auto device = device_driver->ctor(&m_test_service, "hi182x_optical_module_null_test");
    ASSERT_TRUE(device != nullptr);

    // 测试空参数初始化
    status_t ret = device_driver->init(device, nullptr, nullptr);
    EXPECT_EQ(ret, STATUS_ERROR);
}

TEST_F(Hi182xAbiTest, init_hi182x_optical_module_with_params) {
    auto device_driver = m_devices["OpticalTransceiver"];
    ASSERT_TRUE(device_driver != nullptr);

    auto device = static_cast<hi182x_optical_module*>(
        device_driver->ctor(&m_test_service, "hi182x_optical_module_lifecycle"));
    ASSERT_TRUE(device != nullptr);

    mc::mutable_dict config;
    config["bmc.dev.OpticalModule"] = mc::dict{
        {"Manufacturer", "Huawei"}, 
        {"PartNumber", "1234567890"}, 
        {"SerialNumber", "1234567890"},
        {"MediumType", "1000BASE-T"},
        {"ConnectorType", "RJ45"},
        {"TransmissionDistance", 100},
    };
    config["bmc.dev.OpticalModule.Status"] = mc::dict{
        {"TXBiasCurrentMilliAmps", std::vector<double>{100}},
        {"TXPowerMilliWatts", std::vector<double>{100}},
        {"RXPowerMilliWatts", std::vector<double>{100}},
        {"SupplyVoltage", 100},
    };
    EXPECT_TRUE(device->init(config, mc::dict()));
    EXPECT_EQ(device->m_optical_module.Manufacturer.get_value(), "Huawei");
    EXPECT_EQ(device->m_optical_module.PartNumber.get_value(), "1234567890");
    EXPECT_EQ(device->m_optical_module.SerialNumber.get_value(), "1234567890");
    EXPECT_EQ(device->m_optical_module.MediumType.get_value(), "1000BASE-T");
    EXPECT_EQ(device->m_optical_module.ConnectorType.get_value(), "RJ45");
    EXPECT_EQ(device->m_optical_module.TransmissionDistance.get_value(), 100);
    auto value = device->m_optical_module_status.TXBiasCurrentMilliAmps.get_value();
    EXPECT_EQ(value.as<std::vector<double>>(), std::vector<double>{100});
    value = device->m_optical_module_status.TXPowerMilliWatts.get_value();
    EXPECT_EQ(value.as<std::vector<double>>(), std::vector<double>{100});
    value = device->m_optical_module_status.RXPowerMilliWatts.get_value();
    EXPECT_EQ(value.as<std::vector<double>>(), std::vector<double>{100});
    EXPECT_EQ(device->m_optical_module_status.SupplyVoltage.get_value(), 100);
}

TEST_F(Hi182xAbiTest, init_hi182x_optical_module_reset_default_properties) {
    auto device_driver = m_devices["OpticalTransceiver"];
    ASSERT_TRUE(device_driver != nullptr);

    auto device = static_cast<hi182x_optical_module*>(
        device_driver->ctor(&m_test_service, "hi182x_optical_module_lifecycle"));
    ASSERT_TRUE(device != nullptr);

    EXPECT_TRUE(device->reset_default_properties());
    EXPECT_EQ(device->m_optical_module.Manufacturer.get_value(), "");
    EXPECT_EQ(device->m_optical_module.PartNumber.get_value(), "");
    EXPECT_EQ(device->m_optical_module.SerialNumber.get_value(), "");
    EXPECT_EQ(device->m_optical_module.MediumType.get_value(), "");
    EXPECT_EQ(device->m_optical_module.ConnectorType.get_value(), "");
    EXPECT_EQ(device->m_optical_module.TransmissionDistance.get_value(), 0xFFFF);
    EXPECT_EQ(device->m_optical_module.RxLossStatus.get_value(), false);
    EXPECT_EQ(device->m_optical_module.TxFaultStatus.get_value(), false);
    EXPECT_EQ(device->m_optical_module.WaveLengthNanometer.get_value(), "");
    EXPECT_EQ(device->m_optical_module.Identifier.get_value(), "");
    auto value = device->m_optical_module_status.TXBiasCurrentMilliAmps.get_value();
    EXPECT_EQ(value.as<std::vector<double>>(), std::vector<double>{});
    value = device->m_optical_module_status.TXPowerMilliWatts.get_value();
    EXPECT_EQ(value.as<std::vector<double>>(), std::vector<double>{});
    value = device->m_optical_module_status.RXPowerMilliWatts.get_value();
    EXPECT_EQ(value.as<std::vector<double>>(), std::vector<double>{});
    EXPECT_EQ(device->m_optical_module_status.SupplyVoltage.get_value(), 0);
    EXPECT_EQ(device->m_optical_module_status.TXPowerUpperThresholdCritical.get_value(), 0);
    EXPECT_EQ(device->m_optical_module_status.TXPowerLowerThresholdCritical.get_value(), 0);
    EXPECT_EQ(device->m_optical_module_status.VoltageUpperThresholdCritical.get_value(), 0);
}

TEST_F(Hi182xAbiTest, test_hi182x_optical_module_start_ncsi_protocol) {
    auto device_driver = m_devices["OpticalTransceiver"];
    ASSERT_TRUE(device_driver != nullptr);

    auto device = static_cast<hi182x_optical_module*>(
        device_driver->ctor(&m_test_service, "hi182x_optical_module_lifecycle"));
    ASSERT_TRUE(device != nullptr);

    uint16_t phy_addr = mctp::init_phy_addr(0, 0, 0);
    mctp* mctp_object = new mctp(device, phy_addr, MCTP_MESSAGE_TYPE::MCTP_MESSAGE_TYPE_NCSI, "");
    auto m_ncsi_over_mctp_huawei = std::make_shared<ncsi_over_mctp_huawei>(*mctp_object);
    EXPECT_TRUE(device->start_ncsi_protocol(m_ncsi_over_mctp_huawei, mc::milliseconds(1000)));
    EXPECT_TRUE(device->stop());
}


// ========================= 错误处理测试 =========================

TEST_F(Hi182xAbiTest, device_pcienicard_with_null_device) {
    auto device_driver = m_devices["PCIeNicCard"];
    ASSERT_TRUE(device_driver != nullptr);

    void* device = device_driver->ctor(&m_test_service, nullptr);
    EXPECT_EQ(device, nullptr);

    device = device_driver->ctor(nullptr, "hi182x_card_null_params");
    EXPECT_EQ(device, nullptr);

    status_t init_ret = device_driver->init(nullptr, nullptr, nullptr);
    EXPECT_EQ(init_ret, STATUS_ERROR);

    status_t start_ret = device_driver->start(nullptr);
    EXPECT_EQ(start_ret, STATUS_ERROR);

    status_t stop_ret = device_driver->stop(nullptr);
    EXPECT_EQ(stop_ret, STATUS_ERROR);
}

TEST_F(Hi182xAbiTest, device_networkport_with_null_params) {
    auto device_driver = m_devices["NicPort"];
    ASSERT_TRUE(device_driver != nullptr);

    void* device = device_driver->ctor(&m_test_service, nullptr);
    EXPECT_EQ(device, nullptr);

    device = device_driver->ctor(nullptr, "hi182x_port_null_params");
    EXPECT_EQ(device, nullptr);

    status_t init_ret = device_driver->init(nullptr, nullptr, nullptr);
    EXPECT_EQ(init_ret, STATUS_ERROR);

    status_t start_ret = device_driver->start(nullptr);
    EXPECT_EQ(start_ret, STATUS_ERROR);

    status_t stop_ret = device_driver->stop(nullptr);
    EXPECT_EQ(stop_ret, STATUS_ERROR);
}

TEST_F(Hi182xAbiTest, device_opticalmodule_with_null_params) {
    auto device_driver = m_devices["OpticalTransceiver"];
    ASSERT_TRUE(device_driver != nullptr);

    void* device = device_driver->ctor(&m_test_service, nullptr);
    EXPECT_EQ(device, nullptr);

    device = device_driver->ctor(nullptr, "hi182x_optical_module_null_params");
    EXPECT_EQ(device, nullptr);

    status_t init_ret = device_driver->init(nullptr, nullptr, nullptr);
    EXPECT_EQ(init_ret, STATUS_ERROR);

    status_t start_ret = device_driver->start(nullptr);
    EXPECT_EQ(start_ret, STATUS_ERROR);

    status_t stop_ret = device_driver->stop(nullptr);
    EXPECT_EQ(stop_ret, STATUS_ERROR);
}

// ========================= 多设备并发测试 =========================

TEST_F(Hi182xAbiTest, multiple_devices_creation) {
    // 测试同时创建多个不同类型的设备
    std::vector<driver_handle_t> pcie_nic_card_devices;
    std::vector<driver_handle_t> network_port_devices;
    std::vector<driver_handle_t> optical_module_devices;

    // 创建多个PCIeNicCard设备
    auto card_driver = m_devices["PCIeNicCard"];
    for (int i = 0; i < 3; ++i) {
        std::string device_name = "hi182x_card_" + std::to_string(i);
        auto        device      = card_driver->ctor(&m_test_service, device_name.c_str());
        ASSERT_TRUE(device != nullptr);
        pcie_nic_card_devices.push_back(device);
    }

    // 创建多个NetworkPort设备
    auto port_driver = m_devices["NicPort"];
    for (int i = 0; i < 3; ++i) {
        std::string device_name = "hi182x_port_" + std::to_string(i);
        auto        device      = port_driver->ctor(&m_test_service, device_name.c_str());
        ASSERT_TRUE(device != nullptr);
        network_port_devices.push_back(device);
    }

    // 创建多个OpticalModule设备
    auto om_driver = m_devices["OpticalTransceiver"];
    for (int i = 0; i < 3; ++i) {
        std::string device_name = "hi182x_om_" + std::to_string(i);
        auto        device      = om_driver->ctor(&m_test_service, device_name.c_str());
        ASSERT_TRUE(device != nullptr);
        optical_module_devices.push_back(device);
    }

    EXPECT_EQ(pcie_nic_card_devices.size(), 3);
    EXPECT_EQ(network_port_devices.size(), 3);
    EXPECT_EQ(optical_module_devices.size(), 3);
}

TEST_F(Hi182xAbiTest, hi182x_card_full_lifecycle) {
    auto connector = create_test_connector(1, 1, 1);

    // 创建PCIeNicCard设备
    auto device_driver = m_devices["PCIeNicCard"];
    ASSERT_TRUE(device_driver != nullptr);
    auto card_device =
        static_cast<hi182x_card*>(device_driver->ctor(&m_test_service, "hi182x_card_lifecycle"));
    ASSERT_TRUE(card_device != nullptr);

    card_device->set_position("1");
    auto card_csr_object =
        mc::mutable_dict{{"bmc.dev.PcieDevice", mc::dict{{"DeviceName", "test_hi182x_card"}}}};

    status_t card_init_ret = device_driver->init(card_device, &card_csr_object, &connector);
    EXPECT_EQ(card_init_ret, STATUS_OK);

    auto port_driver = m_devices["NicPort"];
    ASSERT_TRUE(port_driver != nullptr);

    auto port_device =
        static_cast<hi182x_port*>(port_driver->ctor(&m_test_service, "hi182x_port_lifecycle"));
    ASSERT_TRUE(port_device != nullptr);

    port_device->set_position("1");
    port_device->set_parent(card_device);
    auto port_csr_object = mc::mutable_dict{{"bmc.dev.NetworkPort", mc::dict{{"PortId", 1}}}};

    status_t port_init_ret = port_driver->init(port_device, &port_csr_object, &connector);
    EXPECT_EQ(port_init_ret, STATUS_OK);

    auto om_driver = m_devices["OpticalTransceiver"];
    ASSERT_TRUE(om_driver != nullptr);

    auto om_device = static_cast<hi182x_optical_module*>(
        om_driver->ctor(&m_test_service, "hi182x_optical_module_lifecycle"));
    ASSERT_TRUE(om_device != nullptr);

    om_device->set_position("1");
    om_device->set_parent(port_device);
    auto om_csr_object = mc::mutable_dict{{"bmc.dev.OpticalModule", mc::dict{{"PortId", 1}}}};

    status_t om_init_ret = om_driver->init(om_device, &om_csr_object, &connector);
    EXPECT_EQ(om_init_ret, STATUS_OK);

    // 启动设备
    status_t card_start_ret = device_driver->start(card_device);
    EXPECT_EQ(card_start_ret, STATUS_OK);
}

// ========================= 工具测试测试 =========================
TEST_F(Hi182xAbiTest, test_hi182x_card_prase_pci_info) {
    std::vector<uint8_t> rsp_data = {
        0, 0, // rsp_code (不相关)
        0, 0, // reason_code (不相关)
        0,       // major_ver (不相关)
        0,       // minor_ver (不相关)
        0,       // update_ver (不相关)
        0,       // alpha1 (不相关)
        0, 0, 0, // reserved
        0,       // alpha2 (不相关)
        'N', 'A', 'M', 'E', '_', 'S', 'T', 'R', 'I', 'N', 'G', ' ', // name_string (12字节)
        22, 6, 3, 1, // firmware_ver (4字节) - 16.06.03.01
        2, 37, // pci_did (不相关)
        25, 229, // pci_vid (不相关)
        0, 161, // pci_ssid (不相关)
        25, 229, // pci_svid (不相关)
        255, 255, 255, 255, // manufacturer_id
        0, 0, 0, 0, // check_sum (不相关)
        0, 0, 0, 0  // FCS (不相关)
    };
    std::string rsp_str(rsp_data.begin(), rsp_data.end());
    // 打印原始数据的十六进制表示
    std::cout << "原始数据 (hex): ";
    for (size_t i = 0; i < rsp_data.size(); ++i) {
        printf("%02x ", rsp_data[i]);
        if ((i + 1) % 16 == 0) std::cout << std::endl;
    }
    std::cout << std::endl;
    auto rsp = reinterpret_cast<get_version_id_rsp*>(const_cast<char*>(rsp_str.data()));

    // 将PCI ID信息转换为16进制字符串格式
    char vid_str[16]  = {0};
    char did_str[16]  = {0};
    char svid_str[16] = {0};
    char sdid_str[16] = {0};

    snprintf(vid_str, sizeof(vid_str), "0x%04x", SHORT_BY_BIG_ENDIAN(rsp->pci_vid));
    snprintf(did_str, sizeof(did_str), "0x%04x", SHORT_BY_BIG_ENDIAN(rsp->pci_did));
    snprintf(svid_str, sizeof(svid_str), "0x%04x", SHORT_BY_BIG_ENDIAN(rsp->pci_svid));
    snprintf(sdid_str, sizeof(sdid_str), "0x%04x", SHORT_BY_BIG_ENDIAN(rsp->pci_ssid));

    EXPECT_STREQ(vid_str, "0x19e5");
    EXPECT_STREQ(did_str, "0x0225");
    EXPECT_STREQ(sdid_str, "0x00a1");
    EXPECT_STREQ(svid_str, "0x19e5");
}

TEST_F(Hi182xAbiTest, test_hi182x_card_dcbx_status) {
    std::vector<uint8_t> rsp_data = {
    0,   0,     // rsp_code (不相关)
    0,   0,     // reason_code (不相关)
    0,          // major_ver (不相关)
    0,          // minor_ver (不相关)
    7,          // update_ver (不相关)
    219,        // alpha1 (不相关)
    0,  1,  2,  // reserved
    0,          // alpha2 (不相关)
    0, 1, 2, 3, 
    4, 5, 6, 7, 
    0, 0, 0, 0, 
    0, 0, 0, 0, 
    100, 
    0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 
};
    std::string rsp_str(rsp_data.begin(), rsp_data.end());
    auto rsp = reinterpret_cast<oem_huawei_dcbx_status_rsp*>(const_cast<char*>(rsp_str.data()));

    ncsi_dcbx_status_t dcbx_status = {};
    memcpy(dcbx_status.cos2_up, rsp->cos2_up, MCTP_NCSI_DCBX_FIELD_LEN);
    memcpy(dcbx_status.up_pgid, rsp->up_pgid, MCTP_NCSI_DCBX_FIELD_LEN);
    memcpy(dcbx_status.pgpct, rsp->pgpct, MCTP_NCSI_DCBX_FIELD_LEN);
    memcpy(dcbx_status.strict, rsp->strict, MCTP_NCSI_DCBX_FIELD_LEN);
    dcbx_status.pfcmap = rsp->pfcmap;

    EXPECT_EQ(dcbx_status.cos2_up[0], 0);
    EXPECT_EQ(dcbx_status.cos2_up[1], 1);
    EXPECT_EQ(dcbx_status.cos2_up[2], 2);
    EXPECT_EQ(dcbx_status.cos2_up[3], 3);
    EXPECT_EQ(dcbx_status.cos2_up[4], 4);
    EXPECT_EQ(dcbx_status.cos2_up[5], 5);
    EXPECT_EQ(dcbx_status.cos2_up[6], 6);
    EXPECT_EQ(dcbx_status.cos2_up[7], 7);

    EXPECT_EQ(dcbx_status.up_pgid[0], 0);
    EXPECT_EQ(dcbx_status.up_pgid[1], 0);
    EXPECT_EQ(dcbx_status.up_pgid[2], 0);
    EXPECT_EQ(dcbx_status.up_pgid[3], 0);
    EXPECT_EQ(dcbx_status.up_pgid[4], 0);
    EXPECT_EQ(dcbx_status.up_pgid[5], 0);
    EXPECT_EQ(dcbx_status.up_pgid[6], 0);
    EXPECT_EQ(dcbx_status.up_pgid[7], 0);

    EXPECT_EQ(dcbx_status.pgpct[0], 100);
    EXPECT_EQ(dcbx_status.pgpct[1], 0);
    EXPECT_EQ(dcbx_status.pgpct[2], 0);
    EXPECT_EQ(dcbx_status.pgpct[3], 0);
    EXPECT_EQ(dcbx_status.pgpct[4], 0);
    EXPECT_EQ(dcbx_status.pgpct[5], 0);
    EXPECT_EQ(dcbx_status.pgpct[6], 0);
    EXPECT_EQ(dcbx_status.pgpct[7], 0);

    EXPECT_EQ(dcbx_status.strict[0], 0);
    EXPECT_EQ(dcbx_status.strict[1], 1);
    EXPECT_EQ(dcbx_status.strict[2], 1);
    EXPECT_EQ(dcbx_status.strict[3], 1);
    EXPECT_EQ(dcbx_status.strict[4], 1);
    EXPECT_EQ(dcbx_status.strict[5], 1);
    EXPECT_EQ(dcbx_status.strict[6], 1);
    EXPECT_EQ(dcbx_status.strict[7], 1);
    EXPECT_EQ(dcbx_status.pfcmap, 0);

}

TEST_F(Hi182xAbiTest, test_hi182x_card_get_port_metrics) {
    std::vector<uint8_t> rsp_data = {
        0, 0, 0, 0, 0, 0, 7, 219, 0, 0, 13, 0, 0, 0, 0, 0,
        0, 18, 136, 216, 0, 0, 0, 0, 0, 18, 108, 212, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 240, 0, 0, 0, 0,
        0, 0, 12, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 8, 241, 0, 0, 0, 0, 0, 0, 11, 250, 0, 0, 0, 0,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 255, 238, 95, 150, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 8, 235, 0, 0, 0, 5, 0, 0, 0, 0,
        0, 0, 12, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 8, 235, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 11, 250,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 18, 136, 216, 0, 0, 0, 0, 0, 0, 0, 0
    };
    std::string rsp_str(rsp_data.begin(), rsp_data.end());
    auto rsp = reinterpret_cast<controller_packet_statistics_rsp*>(const_cast<char*>(rsp_str.data()));

    // 使用字节序转换函数处理多字节字段
    // 对于64位字段，需要手动处理字节序转换
    auto rx_frames = std::to_string(mc::ntoh(rsp->total_bytes_received));
    auto tx_frames = std::to_string(mc::ntoh(rsp->total_bytes_transmitted));

    EXPECT_EQ(rx_frames, "1214680");
    EXPECT_EQ(tx_frames, "1207508");
}

static float covert_micro_to_milli(uint16_t value) {
    if (value == 0xFFFF) {
        return 0.0;
    }

    return value / 1000.0;
}

TEST_F(Hi182xAbiTest, test_hi182x_card_get_optical_module_info) {
    std::vector<uint8_t> rsp_data = {
        0, 0, 0, 0, 0, 0, 7, 219, 0, 0, 13, 0, 76, 57, 57, 81, 70, 48, 50, 48, 
        45, 83, 68, 45, 82, 32, 32, 32, 76, 85, 88, 83, 72, 65, 82, 69, 45, 73, 
        67, 84, 32, 32, 32, 32, 90, 48, 48, 65, 50, 82, 49, 55, 48, 57, 48, 48, 
        48, 48, 54, 49, 17, 3, 35, 0, 255, 255, 0, 90, 0, 0, 12, 178, 0, 0, 255, 255, 
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
        255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0
    };
    std::string rsp_str(rsp_data.begin(), rsp_data.end());
    auto rsp = reinterpret_cast<oem_huawei_optical_module_info_rsp_t*>(rsp_str.data());
    ncsi_optical_module_info_t optical_module_info = {};
    auto optical_module_info_ptr = &optical_module_info;

    memcpy(optical_module_info_ptr->manufacturer, rsp->vendor, 16);
    memcpy(optical_module_info_ptr->part_number, rsp->part_number, 16);
    memcpy(optical_module_info_ptr->serial_number, rsp->serial_number, 16);

    auto manufacturer = std::string(reinterpret_cast<char*>(optical_module_info.manufacturer), sizeof(optical_module_info.manufacturer));
    auto part_number = std::string(reinterpret_cast<char*>(optical_module_info.part_number), sizeof(optical_module_info.part_number));
    auto serial_number = std::string(reinterpret_cast<char*>(optical_module_info.serial_number), sizeof(optical_module_info.serial_number));
    
    auto supply_voltage = covert_micro_to_milli(mc::ntoh(rsp->working_voltage));

    // 去除尾部的空格
    manufacturer.erase(manufacturer.find_last_not_of(' ') + 1);
    part_number.erase(part_number.find_last_not_of(' ') + 1);
    serial_number.erase(serial_number.find_last_not_of(' ') + 1);

    EXPECT_STREQ(manufacturer.c_str(), "LUXSHARE-ICT");
    EXPECT_STREQ(part_number.c_str(), "L99QF020-SD-R");
    EXPECT_STREQ(serial_number.c_str(), "Z00A2R1709000061");    
    EXPECT_EQ(supply_voltage, 3.25);
}


} // namespace test
} // namespace hisi
} // namespace pcie_nic_card
} // namespace drivers